#pragma once

#include "Config.h"

// StoragePolicy: object pointer

template <typename T>
class DefaultSPStorage
{
protected:
	typedef T* StoredType;
	typedef T* PointerType;
	typedef T& ReferenceType;

public:

	DefaultSPStorage() :
	  mPointee(GetDefault())
	{
	}

	DefaultSPStorage(const StoredType& p) :
	  mPointee(p)
	{
	}

	DefaultSPStorage (const DefaultSPStorage& rhs)
	{
	}

	template <typename T1>
	DefaultSPStorage (const DefaultSPStorage<T1>& rhs)
	{
	}

	PointerType operator-> ()
	{
		return mPointee;
	}

	ReferenceType operator* ()
	{
		return *mPointee;
	}

	void Swap(DefaultSPStorage &rhs)
	{
		std::swap(mPointee, rhs.mPointee);
	}

	// friend definitions: friend non-member functions defined inside the class

	friend inline PointerType GetImpl(const DefaultSPStorage& sp)
	{
		return sp.mPointee;
	}

	friend inline const StoredType& GetImplRef(const DefaultSPStorage& sp)
	{
		return sp.mPointee;
	}

	friend inline StoredType& GetImplRef(DefaultSPStorage& sp)
	{
		return sp.mPointee;
	}

protected:

	void Destroy()
	{
		MM_DELETE ( mPointee );
	}

	static StoredType GetDefault()
	{
		return nullptr;
	}

private:
	StoredType mPointee;
};